home *** CD-ROM | disk | FTP | other *** search
/ Aminet 30 / Aminet 30 (1999)(Schatztruhe)[!][Apr 1999].iso / Aminet / util / pack / xpk_Source.lha / xpk_Source / libraries / DUKE / xpkDUKE.c next >
C/C++ Source or Header  |  1998-11-09  |  6KB  |  264 lines

  1. /*
  2.  * This library is mainly intended to demonstrate how to program a sub
  3.  * library.
  4.  */
  5.  
  6. #define VERSION        1
  7.  
  8. #include <xpk/xpksub.h>
  9. #include <exec/memory.h>
  10. #include <proto/exec.h>
  11.  
  12. #define SDI_TO_ANSI
  13. #include "SDI_ASM_STD_protos.h"
  14.  
  15. #ifdef __MAXON__
  16.   #define __asm
  17. #endif
  18.  
  19. #define SysBase (*((struct ExecBase **) 4));
  20.  
  21. #define SCANBUFLEN 32768
  22.  
  23. /*
  24.  * Pack a chunk
  25.  */
  26.  
  27. struct NukeData {
  28.     APTR    inbuf;
  29.     APTR    outbuf;
  30.     APTR    last;
  31.     APTR    next;
  32.     ULONG    cwri;
  33.     ULONG    uwri;
  34.     ULONG    uend;
  35.     ULONG    delpos;
  36.     UWORD    ulen;
  37.     UWORD    clen;
  38.     UWORD    ustop;
  39.     UWORD    ustart;
  40.     UWORD    ucount;
  41.     UWORD    scanrange;
  42.     UWORD    room1;
  43.     UWORD    room2;
  44.     UWORD    room4;
  45.     UWORD    roomN;
  46.     UWORD    data1;
  47.     UWORD    data2;
  48.     ULONG    data4;
  49.     ULONG    dataN;
  50.     ULONG    dest1;
  51.     ULONG    dest2;
  52.     ULONG    dest4;
  53.     ULONG    destN;
  54.     ULONG    dummy;
  55.     ULONG    contbuf;
  56.     ULONG    flags;
  57. };
  58.  
  59. #ifdef __cplusplus
  60. extern "C" {
  61. #endif
  62.  
  63. LONG __asm AsmPack  (register __a4 struct NukeData *ND);
  64. STRPTR __asm AsmUnpack(register __a1 STRPTR wread, register __a4 STRPTR bread,
  65.                         register __a0 STRPTR dst, register __a2 STRPTR end);
  66. #ifdef __cplusplus
  67. }
  68. #endif
  69.  
  70. #define PACKMEM   (65536+SCANBUFLEN)*sizeof(UWORD)+sizeof(struct NukeData)+SCANBUFLEN
  71. #define UNPACKMEM SCANBUFLEN
  72. #define A3000     XPKMF_A3000SPEED
  73.  
  74. static struct XpkMode DukeMode = {
  75.   NULL,       // Next mode
  76.   100,        // Handles up to
  77.   A3000,      // Flags
  78.   PACKMEM,    // Packing memory
  79.   UNPACKMEM,  // Unpacking memory
  80.   36,         // Packing speed
  81.   630,        // Unpacking speed
  82.   454,        // Compression ratio
  83.   0,          // Reserved
  84.   "normal",   // Description
  85. };
  86.  
  87. static struct XpkInfo DukeInfo = {
  88.     1,               /* info version */
  89.     VERSION,         /* lib  version */
  90.     0,               /* master vers  */
  91.     1,               /* ModesVersion */
  92.     (STRPTR) "DUKE", /* short name   */
  93.     (STRPTR) "Duke", /* long name    */
  94.     (STRPTR) "NUKE with a delta preprocessor", /* Description */
  95.     0x44554B45,     /* 'DUKE', 4 letter ID  */
  96.     XPKIF_PK_CHUNK | /* flags        */
  97.     XPKIF_UP_CHUNK,
  98.     30000,           /* max in chunk */
  99.     10,              /* min in chunk */
  100.     30000,           /* def in chunk */
  101.     (STRPTR) "Duking",   /* pk message   */
  102.     (STRPTR) "Unduking", /* up message   */
  103.     (STRPTR) "Duked",    /* pk past msg  */
  104.     (STRPTR) "Unduked",  /* up past msg  */
  105.     50,              /* DefMode      */
  106.     0,               /* Pad          */
  107.     &DukeMode,       /* ModeDesc     */
  108.     0,               /* MinModeDesc  */
  109.     0,               /* MaxModeDesc  */
  110.     0,0,0,0          /* reserved     */
  111. };
  112.  
  113. void DoDelta(STRPTR dst, STRPTR src, LONG len)
  114. {
  115.   UBYTE a=0, b=0;
  116.  
  117.   if (len>0) {
  118.     switch (len & 7) {
  119.       do {
  120.     case 0: *dst++ = (UBYTE) ((b=*src++) - a);
  121.     case 7: *dst++ = (UBYTE) ((a=*src++) - b);
  122.     case 6: *dst++ = (UBYTE) ((b=*src++) - a);
  123.     case 5: *dst++ = (UBYTE) ((a=*src++) - b);
  124.     case 4: *dst++ = (UBYTE) ((b=*src++) - a);
  125.     case 3: *dst++ = (UBYTE) ((a=*src++) - b);
  126.     case 2: *dst++ = (UBYTE) ((b=*src++) - a);
  127.     case 1: *dst++ = (UBYTE) ((a=*src++) - b);
  128.       } while ((len-=8)>0);
  129.     }
  130.   }
  131. }
  132.  
  133. void UndoDelta(STRPTR dst, STRPTR src, LONG len)
  134. {
  135.   UBYTE l = 0;
  136.  
  137.   if (len > 0) {
  138.     switch (len & 7) {
  139.      do {
  140.     case 0: *dst++ = (l+=*src++);
  141.     case 7: *dst++ = (l+=*src++);
  142.     case 6: *dst++ = (l+=*src++);
  143.     case 5: *dst++ = (l+=*src++);
  144.     case 4: *dst++ = (l+=*src++);
  145.     case 3: *dst++ = (l+=*src++);
  146.     case 2: *dst++ = (l+=*src++);
  147.     case 1: *dst++ = (l+=*src++);
  148.       } while ((len-=8)>0);
  149.     }
  150.   }
  151. }
  152.  
  153. /*
  154.  * Returns an info structure about our packer
  155.  */
  156.  
  157. #ifdef __cplusplus
  158. extern "C"
  159. #endif
  160.  
  161. struct XpkInfo *XpksPackerInfo(void)
  162. {
  163.   return &DukeInfo;
  164. }
  165.  
  166. #ifdef __cplusplus
  167. extern "C"
  168. #endif
  169.  
  170. #define LASTSIZE    (65536*sizeof(UWORD))
  171. #define NEXTSIZE    (SCANBUFLEN*sizeof(UWORD))
  172.  
  173. void __asm XpksPackFree(register __a0 struct XpkSubParams *xpar)
  174. {
  175.   struct NukeData *ND = (struct NukeData *) xpar->xsp_Sub[0];
  176.  
  177.   if(xpar->xsp_Sub[1])
  178.   {
  179.     FreeMem((APTR) xpar->xsp_Sub[1], SCANBUFLEN);
  180.     xpar->xsp_Sub[1] = 0;
  181.   }
  182.   if(ND)
  183.   {
  184.     if(ND->last) FreeMem(ND->last, LASTSIZE);
  185.     if(ND->next) FreeMem(ND->next, NEXTSIZE);
  186.     FreeMem(ND, sizeof(struct NukeData));
  187.     xpar->xsp_Sub[0] = 0;
  188.   }
  189. }
  190.  
  191.  
  192. struct NukeData *alloctabs(struct XpkSubParams *xpar)
  193. {
  194.   struct NukeData *ND;
  195.  
  196.   if ((xpar->xsp_Sub[0] = (LONG) (ND = (struct NukeData*) AllocMem(sizeof(struct NukeData),MEMF_CLEAR))) &&
  197.       (ND->last = AllocMem(LASTSIZE,0)) &&
  198.       (ND->next = AllocMem(NEXTSIZE,0)) &&
  199.       (xpar->xsp_Sub[1] = (LONG) AllocMem(SCANBUFLEN,0))) {
  200.     return ND;
  201.   }
  202.   else
  203.   {
  204.     XpksPackFree(xpar);
  205.     return 0;
  206.   }
  207. }
  208.  
  209. #ifdef __cplusplus
  210. extern "C"
  211. #endif
  212.  
  213. LONG __asm XpksPackChunk(register __a0 struct XpkSubParams *xpar )
  214. {
  215.   struct NukeData *ND=(struct NukeData *)xpar->xsp_Sub[0];
  216.  
  217.   if (!ND)
  218.     if (!(ND=alloctabs(xpar)))
  219.       return XPKERR_NOMEM;
  220.  
  221.   DoDelta((STRPTR)xpar->xsp_Sub[1], (STRPTR) xpar->xsp_InBuf, xpar->xsp_InLen);
  222.  
  223.   ND->inbuf = (APTR) xpar->xsp_Sub[1];
  224.   ND->outbuf= xpar->xsp_OutBuf;
  225.   ND->ulen  = (UWORD) xpar->xsp_InLen;
  226.   ND->clen  = (UWORD) (xpar->xsp_OutBufLen-4);
  227.  
  228.   memset(ND->last,0,LASTSIZE);
  229.   memset(ND->next,0,NEXTSIZE);
  230.  
  231.   if(((LONG)(xpar->xsp_OutLen = AsmPack(ND))) <0 || xpar->xsp_OutLen>xpar->xsp_InLen)
  232.   {
  233. /*    XpksPackReset(xpar); ist empty function */
  234.     return XPKERR_EXPANSION;
  235.   }
  236.   return 0;
  237. }
  238.  
  239. #ifdef __cplusplus
  240. extern "C"
  241. #endif
  242.  
  243. LONG __asm XpksUnpackChunk(register __a0 struct XpkSubParams *xpar)
  244. {
  245.   if(!xpar->xsp_Sub[1] && !(xpar->xsp_Sub[1] = (LONG) AllocMem(SCANBUFLEN,0)))
  246.      return XPKERR_NOMEM;
  247.  
  248.   AsmUnpack((STRPTR) xpar->xsp_InBuf,  (STRPTR)xpar->xsp_InBuf  + xpar->xsp_InLen,
  249.             (STRPTR)xpar->xsp_Sub[1], (STRPTR)xpar->xsp_Sub[1] + xpar->xsp_OutLen);
  250.  
  251.   UndoDelta((STRPTR)xpar->xsp_OutBuf, (STRPTR )xpar->xsp_Sub[1], xpar->xsp_OutLen);   
  252.  
  253.   return 0;
  254. }
  255.  
  256. #ifdef __cplusplus
  257. extern "C"
  258. #endif
  259.  
  260. void __asm XpksUnpackFree(register __a0 struct XpkSubParams *xpar)
  261. {
  262.   if (xpar->xsp_Sub[1]) FreeMem((APTR)xpar->xsp_Sub[1], SCANBUFLEN), xpar->xsp_Sub[1]=0;
  263. }
  264.